package com.opcode.nebulamobil.base.fragments.dialogfragments;

import java.util.ArrayList;

import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.DialogInterface.OnShowListener;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;

import com.opcode.nebulamobil.R;
import com.opcode.nebulamobil.base.activities.FragmentActivityBase;
import com.opcode.nebulamobil.base.adapters.ServerListAdapter;
import com.opcode.nebulamobil.base.components.ButtonBase;
import com.opcode.nebulamobil.base.components.ListViewBase;
import com.opcode.nebulamobil.base.components.TextViewBase;
import com.opcode.nebulamobil.base.interfaces.OnButtonBaseClickListener;
import com.opcode.nebulamobil.base.interfaces.OnListViewBaseItemClickListener;
import com.opcode.nebulamobil.base.interfaces.ResponseListener;
import com.opcode.nebulamobil.base.interfaces.TimerListener;
import com.opcode.nebulamobil.enums.TwoButtonDialogType;
import com.opcode.nebulamobil.information.ApplicationInfo;
import com.opcode.nebulamobil.information.dataforms.costadataforms.SettingsDataForm;
import com.opcode.nebulamobil.information.requests.costarequests.DeliveryConfirmReq;
import com.opcode.nebulamobil.information.responses.JSONResponse;
import com.opcode.nebulamobil.information.responses.costaresponses.AppInfoResp;
import com.opcode.nebulamobil.information.responses.costaresponses.DeliveryConfirmResp;
import com.opcode.nebulamobil.utility.JsonConverter;
import com.opcode.nebulamobil.utility.STSFileManager;
import com.opcode.nebulamobil.utility.TimerBase;
import com.opcode.nebulamobil.utility.UniqueIdCreator;

/**
 * İki butona ve bir mesaj alanına sahip dialoglar için tasarlanmış olan sınıf dosyasıdır.
 * @author Okan ERDOĞAN
 *
 * 22 Eyl 2014
 */
public class TwoButtonDialogFragmentBase extends DialogFragmentBase implements ResponseListener{

	/*
	 * Fragment'a ait layout dosyasını tutar.
	 */
	private View vi;
	
	
	/*
	 * DialogFragment'ta kullanıcıya gösterilecek olan mesaj
	 */
	private String message;
	
	/*
	 * Parametre olarak alınan intent nesnesine ait nesne referansidir.
	 * Bu referans sayesinde onay işlemi yapıldıktan sonra hangi activitenin açılacağı belirlenir.
	 */
	private Intent intent;
	
	/*
	 * 
	 */
	private JSONResponse response;
	 
	/*
	 * 
	 */
	private ArrayList<AppInfoResp> appInfoRespList;
	
	/*
	 * 
	 */
	private DeliveryConfirmResp deliveryConfirmResp;
	
	/*
	 * 
	 */
	private TwoButtonDialogType twoButtonDialogType;
	
	/*
	 * 
	 */
	private TimerBase timerBase;
	
	/*
	 * 
	 */
	private ServerListAdapter serverListAdaper;
	
	/*
	 * 
	 */
	private Handler myHandler = null;
	private Runnable myRunnable = null;
	
	/*
	 * 
	 */
	private SettingsDataForm settingsInfo;
	
	/*
	 * 
	 */
	private RoundedProgressDialogBase roundedProgressDialogBase;
	
	public static boolean connectionLostDialogShowing=false;

	public TwoButtonDialogFragmentBase(){
		
	}
	
	/**
	 * 
	 * @param twoButtonDialogType
	 */
	public TwoButtonDialogFragmentBase(TwoButtonDialogType twoButtonDialogType){
		this.twoButtonDialogType=twoButtonDialogType;
	}
	
	
	/**
	 * 
	 * @param message
	 * @param twoButtonDialogType
	 */
	public TwoButtonDialogFragmentBase(String message,TwoButtonDialogType twoButtonDialogType){
		this.message=message;
		this.twoButtonDialogType=twoButtonDialogType;
	}
	
	
	/**
	 * 
	 * @param message
	 * @param intent
	 * @param twoButtonDialogType
	 */
	public TwoButtonDialogFragmentBase(String message,Intent intent,TwoButtonDialogType twoButtonDialogType){
		this.message=message;
		this.intent=intent;
		this.twoButtonDialogType=twoButtonDialogType;
	}
	
	
	/**
	 * 
	 * @param response
	 * @param twoButtonDialogType
	 */
	public TwoButtonDialogFragmentBase(JSONResponse response,TwoButtonDialogType twoButtonDialogType){
		this.response=response;
		this.twoButtonDialogType=twoButtonDialogType;
	}
	
	
	/**
	 * 
	 */
	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {		
		
		if(twoButtonDialogType.equals(TwoButtonDialogType.CONNECTION_LOST_DIALOG)){
			this.vi = inflater.inflate(R.layout.connection_lost_dialog, container,false);
			this.createConnectionLostDialog();
		}else if(twoButtonDialogType.equals(TwoButtonDialogType.ORDER_PREPARE_DIALOG)){
			this.vi = inflater.inflate(R.layout.two_button_dialog_fragment_layout, container,false);
			this.createOrderPrepareDialog();
		}else{
			this.vi = inflater.inflate(R.layout.two_button_dialog_fragment_layout, container,false);
			this.createDefaultDialog();
		}
		
		roundedProgressDialogBase=new RoundedProgressDialogBase();
		
		
		return this.vi;
	}
	
	
	
	
	//---------------------------Varsayılan iki butonlu diyalog---------------
	/**
	 * Varsayılan olarak çalışan metoddur. Bu dialogun açılması durumunda onay butonuna basma halinde parametre olarak verilen intent açılır.
	 */
	private void createDefaultDialog(){
		TextViewBase dialog_message=(TextViewBase) this.vi.findViewById(R.id.dialog_message);
		if(this.message!=null){
			dialog_message.setText(this.message);
		}
		
		//Onay işlemi yapıldığı zaman bu bölüm işletilir.
		ButtonBase confirm_button=(ButtonBase) this.vi.findViewById(R.id.confirm_button);
		confirm_button.setOnButtonBaseClickListener(new OnButtonBaseClickListener() {
			
			@Override
			public void onButtonBaseClick(View v) {	
				
				if(intent!=null){
					startActivity(intent);
				}
			}
		});
		
		
		
		//Reddetme işlemi yapıldıktan sonra bu bölüm işletilir.
		ButtonBase decline_button=(ButtonBase) this.vi.findViewById(R.id.decline_button);
		decline_button.setOnButtonBaseClickListener(new OnButtonBaseClickListener() {
			
			@Override
			public void onButtonBaseClick(View v) {	
				dismiss();
			}
		});
	}
	
	
	
	
	//---------------------------Bağlantı kopması halinde açılacak olan diyalog--------------

	/**
	 * Bağlantı kopması halinde bu metod çalıştırılarak dialog oluşturulur.
	 */
	private void createConnectionLostDialog(){
		
		this.myHandler = new Handler();
		this.settingsInfo=new SettingsDataForm();
		
		ButtonBase tryAgainButton=(ButtonBase) this.vi.findViewById(R.id.try_again_button);
		TextViewBase tryAgainStatusInfo=(TextViewBase) this.vi.findViewById(R.id.try_again_status_info);
		ButtonBase updateServerInfoButton=(ButtonBase) this.vi.findViewById(R.id.update_server_info_button);
		ButtonBase searchServer=(ButtonBase) this.vi.findViewById(R.id.search_server);
		ListViewBase searchServerResults=(ListViewBase) this.vi.findViewById(R.id.search_server_results);

		this.appInfoRespList=new ArrayList<AppInfoResp>();		
		this.serverListAdaper=new ServerListAdapter(getActivity(), R.layout.server_list_item, this.appInfoRespList);
		searchServerResults.setAdapter(serverListAdaper);
		
		ApplicationInfo.setResponseListener(this);
		if(this.message!=null){
			//tryAgainStatusInfo.setText(this.message);
			tryAgainStatusInfo.setText("Nebula'yı bulabilmek için tara butonuna basınız.");
		}else{
			tryAgainStatusInfo.setText("Nebula'yı bulabilmek için tara butonuna basınız.");
		}
		
		tryAgainButton.setVisibility(View.GONE);
		//tryAgainStatusInfo.setVisibility(View.GONE);
		updateServerInfoButton.setVisibility(View.GONE);
		
		tryAgainButton.setOnButtonBaseClickListener(new OnButtonBaseClickListener() {

			@Override
			public void onButtonBaseClick(View v) {	
				dismiss();
				ApplicationInfo.getTryConnectionCommandListener().tryConnectionAgain();
			}
		});
	
		
		updateServerInfoButton.setOnButtonBaseClickListener(new OnButtonBaseClickListener() {

			@Override
			public void onButtonBaseClick(View v) {		
				dismiss();
				((FragmentActivityBase)getActivity()).showGeneralDialog(new SettingsDialogFragment(), "SETTING_DIALOG");

			}
			
		});
		
		searchServer.setOnButtonBaseClickListener(new OnButtonBaseClickListener() {
			
			@Override
			public void onButtonBaseClick(View v) {

				ApplicationInfo.setResponseListener(TwoButtonDialogFragmentBase.this);

				appInfoRespList.clear();
				
				((FragmentActivityBase)getActivity()).showGeneralDialog(roundedProgressDialogBase, "TWO_BUTTON_PROGRESS_DIALOG");
				ApplicationInfo.getNebulaSearchListener().searchNebula();	
			
			}
		});
		
		
		searchServerResults.setOnListViewBaseItemClickListener(new OnListViewBaseItemClickListener() {
			
			@Override
			public void onListViewItemClick(AdapterView<?> parent, View view,int position, long id) {

				ApplicationInfo.setResponseListener(ApplicationInfo.getResponsiveFragmentBase());
				
				AppInfoResp appResp=(AppInfoResp) appInfoRespList.get(position);
				if(appResp!=null){

					settingsInfo.setServerIp(appResp.getIpAddress());
					settingsInfo.setServerPort(5513);
					
					((FragmentActivityBase)getActivity()).createSharedPreferencesManager("sharedpreferences",getActivity());
					((FragmentActivityBase)getActivity()).writeToSharedPreferences("settingsInfo", JsonConverter.toJsonString(settingsInfo));
									
					STSFileManager.getFileOperator().writer(""+settingsInfo.getServerIp()+":"+settingsInfo.getServerPort());
					if(ApplicationInfo.getTryConnectionCommandListener()!=null){
						dismiss();
						TwoButtonDialogFragmentBase.connectionLostDialogShowing=false;

						ApplicationInfo.getTryConnectionCommandListener().tryConnectionAgain();
					}
				}
			
			}
		});
		
		this.myRunnable = new Runnable() {
			public void run() {
				serverListAdaper.updateList(appInfoRespList);		
			}
		};
		
		TwoButtonDialogFragmentBase.connectionLostDialogShowing=true;
	}
	
	
	
	//---------------------------Siparişin hazırlanması durumunda açılacak olan diyalog---------------
	/**
	 * Mutfakta hazırlanan bir sipariş olduğunda bu metod tarafından oluşturulan dialog kullanıcıya gösterilir.
	 */
	private void createOrderPrepareDialog(){		
		
		this.deliveryConfirmResp=(DeliveryConfirmResp) this.response;
		TextViewBase dialog_message=(TextViewBase) this.vi.findViewById(R.id.dialog_message);
		TextViewBase header_message=(TextViewBase) this.vi.findViewById(R.id.header_message);
		if(this.deliveryConfirmResp!=null){
			dialog_message.setText(this.deliveryConfirmResp.getMessage());
			header_message.setText(this.deliveryConfirmResp.getTableName());
		}
		
		//Onay işlemi yapıldığı zaman bu bölüm işletilir.
		ButtonBase confirm_button=(ButtonBase) this.vi.findViewById(R.id.confirm_button);
		confirm_button.setOnButtonBaseClickListener(new OnButtonBaseClickListener() {
			
			@Override
			public void onButtonBaseClick(View v) {	
				createOrderPrepareRequest(true);
				dismiss();
				
			}
		});

		//Reddetme işlemi yapıldıktan sonra bu bölüm işletilir.
		ButtonBase decline_button=(ButtonBase) this.vi.findViewById(R.id.decline_button);
		decline_button.setOnButtonBaseClickListener(new OnButtonBaseClickListener() {
			
			@Override
			public void onButtonBaseClick(View v) {	
				createOrderPrepareRequest(false);
				dismiss();
			}
		});
		
		TimerListener orderPrepareTimerListener=new TimerListener(){

			@Override
			public void timeFinished() {
				//createOrderPrepareRequest(false);
				//TODO Siparişin hazırlandığına dair açılan dialog'un kendi kendine kapanması engellendi. Burası hataya neden oluyordu.
				//dismiss();
			}
			
		};
		
		this.timerBase=new TimerBase(orderPrepareTimerListener);
		
		Dialog dialog = this.getDialog();
		dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCancelable(false);
        dialog.getWindow().setWindowAnimations(android.R.style.Animation_Dialog);
        dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        dialog.getWindow().getAttributes().dimAmount = 0.55f;
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(0)); 
        
        dialog.setOnShowListener(new OnShowListener() {
			
			@Override
			public void onShow(DialogInterface dialog) {
				timerBase.schedule(deliveryConfirmResp.getWaitTime());			
			}
		});
        
        dialog.setOnDismissListener(new OnDismissListener() {
			
			@Override
			public void onDismiss(DialogInterface arg0) {
				System.out.println("Timer durduruldu.");
				timerBase.cancelTimer();
			}
		});
        
        dialog.setOnCancelListener(new OnCancelListener() {
			
			@Override
			public void onCancel(DialogInterface dialog) {
				
			}
		});	
	}
	
	
	/**
	 * Eğer sipariş hazırlandı talebi personel tarafından görülmşse tamam butonuna basılır. Bu durumda sunucuya personelin yemeği görüp, almaya gittiği bilgisi verilir.
	 */
	public void createOrderPrepareRequest(boolean operation){
		DeliveryConfirmReq deliveryConfirmReq=new DeliveryConfirmReq();
		deliveryConfirmReq.setTableId(deliveryConfirmResp.getTableId());
		deliveryConfirmReq.setOrderID(deliveryConfirmResp.getOrderID());
		deliveryConfirmReq.setRequestId(UniqueIdCreator.createUniqueID());
		deliveryConfirmReq.setType("DeliveryConfirmReq");
		deliveryConfirmReq.setOperation(operation);
			
		ApplicationInfo.getRequestListener().jsonRequestCame(JsonConverter.toJsonString(deliveryConfirmReq));

	}

	/**
	 * Sunucudan bir cevap geldiği zaman tetiklenir.
	 */
	@Override
	public void responseCame(String response) {
		JSONResponse responseObject=(JSONResponse) JsonConverter.fromJsonString(response, JSONResponse.class);
		if(responseObject.getType().equals("AppInfoResp")){
			AppInfoResp appInfoResp=(AppInfoResp) JsonConverter.fromJsonString(response, AppInfoResp.class);

			// Burada yeni gelen bilgi daha önceden listeye kayıt edilmiş mi diye bakılıyor.
			// Eğer bu bilgi daha önceden sunucuda kayıtlıysa öncelikle kayıltı veriyi siliyor ve veri en güncel haliyle tekrar kayıt ediliyor.
			for(int i=0;i<appInfoRespList.size();i++){
				if(appInfoRespList.get(i).getIpAddress().equals(appInfoResp.getIpAddress())){
					appInfoRespList.remove(i);
					break;
				}
			}
			
			this.appInfoRespList.add(appInfoResp);

			
			myHandler.post(myRunnable);
			((FragmentActivityBase)getActivity()).closeGeneralDialog(roundedProgressDialogBase, "TWO_BUTTON_PROGRESS_DIALOG");

		}
	}
}
